<?php

namespace app\company\controller;

use app\company\model\DeliverTaskImg;
use app\company\model\Goods;
use app\company\model\OrderTest;
use app\company\model\Store as StoreModel;
use app\company\validate\StoreOrderValidate;
use app\mini\model\StoreOrderDetail;
use app\mini\model\CompanyGoodsChangeLog;
use app\service\traits\Crud;
use app\company\model\StoreOrder as StoreOrderModel;
use app\company\model\StoreUser;
use Exception;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\facade\Request;
use think\Response;

class StoreOrder extends Base
{
    private StoreOrderModel $model;

    use Crud;

    public function initialize()
    {
        parent::initialize();
        $this->model         = new StoreOrderModel();
        $this->validateClass = StoreOrderValidate::class;
        $this->field         = 'id,deliver_task_id,no,channel,company_id,store_id,salesman_id,create_time,order_status,pay_type,settlement_status';
        $this->append        = "store_order_status_text,channel_text,pay_type_text,settlement_status_text";
        $this->isGs          = true;
        $this->withSearch    = 'id,no,create_time,order_status,settlement_status';
    }

    public function format($list): mixed
    {
        return $list->each(function ($item) {
            //是否业务员
            $item->is_salesman = $item->salesman_id ? '是' : '否';
            //门店
            $item->store_name = $item->store()->withTrashed()->value('name');
            //商品总数
            $item->total_num = $item->storeOrderDetails()->sum('quantity');
            //商品种类数
            $item->total_category = $item->storeOrderDetails()->count();
            //单据完成时间
            $item->finish_time = 0;
            if (in_array($item->order_status, [4, 5])) {
                $item->finish_time = $item->storeOrderLogs()->max('create_time');
            }
            $item->finish_time = setDates($item->finish_time);
            //图片凭证
            $item->imgs = DeliverTaskImg::where('deliver_task_id',$item->deliver_task_id)
                ->where('store_id',$item->store_id)->select();
        });
    }


    /**
     * 分账信息
     * @return Response
     */
    public function profit(): Response
    {
        $param = request()->param();
        validate($this->validateClass)->scene('list')->check($param);
        $sql   = $this->model->Gs()->orderStatus(4)->where("credit_status",2);//账单未出不展示
//        if(!empty($param['create_time'])){
//            $param['create_time'] = [
//                strtotime(date('Y-m-d',strtotime($param['create_time'][0])).'00:00:00'),
//                strtotime(date('Y-m-d',strtotime($param['create_time'][1])).'23:59:59'),
//            ];
//        }
        $sql   = $sql->withSearch($this->withSearch, $param)->field('id,no,create_time,order_status,settlement_status,channel,pay_type');
        $count = $sql->count();
        if (Request::param('is_export', 0) != 1) $sql = $sql->page($param['page'], $param['limit']);
        $list = $sql->order($this->orderSort)->select()->each(function ($item) {
            //订单总金额
            $item->total_money = $item->storeOrderDetails()->sum('amount');
            //实收金额
            $item->real_money = $item->total_money;
            if ($item->pay_type == 2) {
                $item->real_money = bcmul($item->total_money, config('platform.wechat_profit'), 2);
            }
            //分佣信息
            //合伙人分佣
            $item->company_profit = $item->storeOrderProfits()->sum('company_profit');
            //平台分佣
            $item->platform_profit = $item->storeOrderProfits()->sum('platform_profit');
            //司机分佣
            $item->driver_profit = $item->storeOrderProfits()->sum('driver_profit');
        })->append(explode(',', $this->append));

        //已结算金额
        $settled_arr   = $this->model->gs()->where('settlement_status', 2)
                                     ->withSum('storeOrderDetails', 'amount')
                                     ->orderStatus(4)
                                     ->withSearch($this->withSearch, $param)
                                     ->select()->column('store_order_details_sum');

        $settled_wx_arr   = $this->model->gs()->where('settlement_status', 2)
                                        ->withSum('storeOrderDetails', 'amount')
                                        ->orderStatus(4)->where('pay_type', 2)
                                        ->withSearch($this->withSearch, $param)
                                        ->select()->column('store_order_details_sum');
        $settled_wx_money = bcadd(array_sum($settled_wx_arr), 0, 2);
        $settled_wx_money = bcmul($settled_wx_money, (config('platform.wechat_profit') - 1), 2);
        $settled_money    = bcadd(array_sum($settled_arr), $settled_wx_money, 2);
        //未结算金额
        $unsettled_arr   = $this->model->gs()->where('settlement_status', 1)
                                       ->withSum('storeOrderDetails', 'amount')
                                       ->orderStatus(4)
                                       ->withSearch($this->withSearch, $param)
                                       ->select()->column('store_order_details_sum');
        $unsettled_wx_arr   = $this->model->gs()->where('settlement_status', 1)
                                          ->withSum('storeOrderDetails', 'amount')
                                          ->orderStatus(4)->where('pay_type', 2)
                                          ->withSearch($this->withSearch, $param)
                                          ->select()->column('store_order_details_sum');
        $unsettled_wx_money = bcadd(array_sum($unsettled_wx_arr), 0, 2);
        $unsettled_wx_money = bcmul($unsettled_wx_money, (config('platform.wechat_profit') - 1), 2);
        $unsettled_money    = bcadd(array_sum($unsettled_arr), $unsettled_wx_money, 2);

        return $this->success('获取成功', compact('count', 'list', 'settled_money', 'unsettled_money'));
    }

    public function detailFormat($info)
    {
        //门店信息
        $info->store      = $info->store()->withTrashed()->field('id,name,address')->find();
        $info->store_user = $info->store->storeUsers()->field('id,real_name,mobile')->find();
        $field              = 'id,goods_id,goods_rule_id,money,quantity,amount,store_user_id,is_send';
        $info->order_detail = $info->storeOrderDetails()->field($field)->select()->each(function ($item) use ($info) {
            $item->goods_name  = $item->goods()->withTrashed()->value('name');
            $item->goods_image = $item->goodsRule()->withTrashed()->value('img');
            $item->spec_name   = $item->goodsRule()->withTrashed()->value('spec_name');
            if($item->is_send == 1){
                $item->old_money = $item->money;
                $changeLog = CompanyGoodsChangeLog::field('new_money')
                            ->where('store_id', $info->store->id)
                            ->where('goods_rule_id', $item->goods_rule_id)
                            ->where('store_user_id', $item->store_user_id)
                            ->order('id desc')
                            ->find();
                if($changeLog){
                    $item->money = $changeLog->new_money;
                }
            }
        });
        $info->order_log    = $info->storeOrderLogs()->field('id,order_status,create_time')->select();
        //订单总价
        $info->total_amount = $info->storeOrderDetails()->sum('amount');
        //是否业务员
        $info->is_salesman   = $info->salesman_id ? '是' : '否';
        $info->salesman_name = StoreUser::where('id', $info->salesman_id)->withTrashed()->value('real_name');
        //大额支付信息
        $info->platform_large = config('platform.large');
        //配送图片凭证
        $info->imgs = DeliverTaskImg::where('deliver_task_id',$info->deliver_task_id)->where('store_id',$info->store_id)->select();
        return $info;
    }

    public function importExcel(): Response
    {
        $this->model->startTrans();
        try {
            $file = request()->file('file'); // 获取上传的文件
            if (!$file) {
                return $this->error('文件上传失败');
            }
            $reader = IOFactory::createReaderForFile($file);
            $reader->setReadDataOnly(true);
            $spreadsheet   = $reader->load($file);
            $sheet         = $spreadsheet->getActiveSheet();
            $highestRow    = $sheet->getHighestRow();
            $highestColumn = $sheet->getHighestColumn();
            $template = [
                '单据','单据时间','业务员','客户名称',
                '仓库','业务属性','商品名称','下单数量','单位名称',
               '大单位价格','下单金额','整单备注','明细备注',
            ];
            $data = $sheet->toArray();
            // 判断$template 和 $data[0] 是否一致
            if($template != $data[0]) return $this->error('模板不匹配');

            $failed = [];
            $errorList        = []; // 存放字段错误信息
            $failedImports    = []; // 记录导入失败数据
            $failedImportsNum = 0; // 记录导入失败的数量
            for ($row = 2; $row <= $highestRow; $row++) {
                // 读取单元格数据
                $data            = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, '',
                                                        true, true, true);
                // 数据处理
                $goodsName = trim($data[$row]['G']);
                // 单位
//                $unit = trim($data[$row]['I']);
//                if($unit == '瓶'){
//                    $errorList[] = ['goods_name'=>$goodsName,'msg'=>'单位不能为瓶，请修重新换算并修改表格'];
//                    $failedImports[] = $data[$row];
//                    $failedImportsNum++;
//                    continue;
//                }
//                // 查询系统商品是否存在该商品
                $goodsId = $this->getGoodsId($goodsName);
                if(!$goodsId){
                    $errorList[] = ['goods_name'=>$goodsName,'msg'=>'系统商品不存在'];
                    $failedImports[] = $data[$row];
                    $failedImportsNum++;
                    continue;
                }
                // 判断仓库库存数量
//                $storeStock = $this->getStoreStock($goodsId);
                $failed[] = $data[$row];
            }
            $res = $this->getFields($failed);
            // 插入系统订单
            $this->addStoreOrder();
            $this->model->commit();
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
        if($failedImportsNum > 0){
            $errorMsg    = "出现" . $failedImportsNum . "条数据导入失败，请下载错误数据并修改重新导入";
            $errorDetail = compact('errorMsg', 'errorList', 'failedImports');
            return $this->error('部分导入失败', $errorDetail);
        }
        return $this->success('导入成功',compact('errorList','template','failedImports','failedImportsNum'));
    }

    private function getFields(array $failedImports): bool
    {
        foreach ($failedImports as $v) {
            $fields                = [
                'no'            => trim($v['A']),
                'no_create_time'   => (int)trim(strtotime($v['B'])),
                'create_time'   => time(),
                'salesman_name' => trim($v['C']),
                'store_name'    => trim($v['D']),
                'yw_type'       => trim($v['F']),
                'goods_name'    => trim($v['G']),
                'quantity'      => trim($v['H']),
                'unit'          => trim($v['I']),
                'money'         => trim($v['J']),
                'amount'        => trim($v['K']),
                'remark'        => trim($v['L']),
                'company_id'    => $this->company_id,
            ];
            // 获取业务员id
            $fields['salesman_id'] = $this->getSalesmanId($fields['salesman_name']);
            // 获取门店ID
            $fields['store_id']    = $this->getStoreId($fields['store_name']);
            // 获取商品ID
            $fields['goods_id']    = $this->getGoodsId($fields['goods_name']);
            $orderTestModel = OrderTest::where(['no'=>$fields['no']])
                                  ->where('goods_id',$fields['goods_id'])
                                  ->where('money',$fields['money'])
                                  ->where('amount',$fields['amount'])
                                  ->find();
            if(!$orderTestModel){
                OrderTest::create($fields);
            }else{
                OrderTest::where(['no'=>$fields['no']])
                         ->where('goods_id',$fields['goods_id'])
                         ->update($fields);
            }
        }
        return true;
    }

    private function getSalesmanId(mixed $yw_user)
    {
        $salesman_id = StoreUser::where('real_name', $yw_user)
                                ->where('is_salesman', 1)
                                ->value('id');
        return $salesman_id ?? 0;
    }

    private function getStoreId(mixed $store_name)
    {
        $storeId = StoreModel::where('name', $store_name)
                             ->value('id');
        return $storeId ?? 0;
    }

    private function getGoodsId(mixed $goods_name)
    {
        $goods_id = Goods::where('name', $goods_name)
                         ->value('id');
        return $goods_id ?? 0;
    }

    private function addStoreOrder(): void
    {
        OrderTest::where('company_id', $this->company_id)
                 ->whereTime('create_time', 'today')
                 ->group('no')
                 ->select()
                 ->each(function ($item) {
                     $orderModel = StoreOrderModel::where('no', $item->no)->find();
                     if(!$orderModel) $orderModel = new StoreOrderModel();
                     $orderModel->company_id = $item->company_id;
                     $orderModel->no = $item->no;
                     $orderModel->store_id = $item->store_id;
                     $orderModel->pay_type = 8;
                     $orderModel->order_status = 4;
                     $orderModel->buyer_remark = $item->remark;
                     $orderModel->salesman_id = $item->salesman_id;
                     $orderModel->create_time = $item->no_create_time;
                     $orderModel->save();

                     if($orderModel){
                         // 创建详情
                         OrderTest::where('no',$item->no)
                                  ->select()
                                  ->each(function ($order) use ($orderModel){
                                      $orderDetailModel = StoreOrderDetail::where('store_order_id',$orderModel->id)
                                          ->where('goods_id',$order->goods_id)
                                          ->where('money',$order->money)
                                          ->where('amount',$order->amount)
                                          ->find();
                                      if($orderDetailModel){
                                          $old_num = $orderDetailModel->quantity;
                                          $now_num = $order->quantity;
                                          if($old_num > $now_num){
                                              $stockNum = $old_num - $now_num;
                                              \app\company\model\CompanyOrderStorage::where('company_id', $order->company_id)
                                                                                    ->where('goods_id', $order->goods_id)
                                                                                    ->inc('quantity', $stockNum)->save();
                                          }else{
                                              $stockNum = $now_num - $old_num;
                                              \app\company\model\CompanyOrderStorage::where('company_id', $order->company_id)
                                                                                    ->where('goods_id', $order->goods_id)
                                                                                    ->dec('quantity', $stockNum)->save();
                                          }
                                      }
                                      if(!$orderDetailModel){
                                          $orderDetailModel = new StoreOrderDetail();
                                          \app\company\model\CompanyOrderStorage::where('company_id', $order->company_id)
                                                                                ->where('goods_id', $order->goods_id)
                                                                                ->dec('quantity', $order->quantity)->save();
                                      }
                                      $orderDetailModel->store_order_id = $orderModel->id;
                                      $orderDetailModel->store_user_id = $orderModel->salesman_id;
                                      $orderDetailModel->goods_id = $order->goods_id;
                                      $orderDetailModel->quantity = $order->quantity;
                                      $orderDetailModel->money = $order->money;
                                      $orderDetailModel->amount = $order->amount;
                                      $orderDetailModel->create_time = $order->no_create_time;
                                      $orderDetailModel->save();
                                  });
                     }
                 });
    }


}